/**
 * Licensed under the Apache License Version 2.0.
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations
 * under the License.
 */
package net.interknit.knitter.cg.template;

import java.io.File;
import java.io.InputStreamReader;
import java.io.PrintStream;

import net.interknit.knitter.cg.CGMain;
import net.interknit.knitter.cg.util.ReflectionHelper;
import net.interknit.knitter.cg.util.Utils;

/**
 *
 */
public class TemplateWriter
{
	private final Template template;
	private final File outputDirectory;

	public TemplateWriter(Template template)
	{
		this.template = template;

		String rootSrcDir = CGMain.getInstance().getCGConfig().getRootSourceDirectory();

		outputDirectory = new File(rootSrcDir, template.getJavaPackageName().replace('.', '/'));

		outputDirectory.mkdirs();

		String outputDirPath = outputDirectory.getAbsolutePath();

		if(! outputDirectory.exists() || ! outputDirectory.isDirectory())
		{
			throw new RuntimeException("Could not create source directory '" + outputDirPath + "'. " +
					"Source generation was aborted. Please check the permissions for this directory and" +
					"retry source generation.");
		}
	}

	public Template getTemplate()
	{
		return template;
	}

	public File getOutputDirectory()
	{
		return outputDirectory;
	}

	protected String getTemplateResourcePath()
	{
		String templateName = getTemplate().getTemplateName();

		String myPkgName = ReflectionHelper.getPackageName(this.getClass());

		// e.g., net.interknit.knitter.cg.writer.templates.MapTypeTemplate.template
		return myPkgName.replace('.', '/') + "/templates/" + templateName + ".template";
	}

	public void write()
	{
		PrintStream out = null;
		try
		{
			String content = "";

			try
			{
				String packageName = template.getJavaPackageName();

				content += "package " + packageName + ";" + "\n";

				content += Utils.readResourceAsString(
						new InputStreamReader(
								getClass().getClassLoader().getResourceAsStream(
										getTemplateResourcePath())));
			}
			catch(Exception templateNotFound)
			{
				CGMain.getInstance().log("Could not find a source template for '" +
						template.getTemplateName() + "' (due to " +
						templateNotFound.getMessage() + "). " +
						"Skipping source generation for this template.", CGMain.LOG_PRIORITY_DEBUG);

				return;
			}

			for(String placeholder : template.getPlaceholders())
				content = content.replaceAll(
						"@" + placeholder + "@",
						template.value(placeholder));

			File sourceFile = new File(getOutputDirectory(), template.getJavaClassName() + ".java");

			if(template.skipSourceGeneration())
			{
				CGMain.getInstance().log("Skipping generation of '" + sourceFile.getAbsolutePath() + "' " +
						"as it is not being referenced elsewhere.", CGMain.LOG_PRIORITY_DEBUG);
				return;
			}

			out = new PrintStream(sourceFile);

			out.println(content);

			CGMain.getInstance().log("Source file " + sourceFile.getAbsolutePath() + " written successfully.");
		}
		catch(Exception e)
		{
			throw new RuntimeException(e);
		}
		finally
		{
			if(out != null) out.close();
		}
	}
}
